<template>
  <div class="count">
    <p :class="{disable: input <= min}"
       class="decrement"
       @click="input--">
      -
    </p>
    <div>
      <input ref="eInput"
             v-model="input"
             type="text"
             @focusout="handleFocusout($event)"/>
    </div>
    <p :class="{disable: input >= max}"
       class="increment"
       @click="input++">
      +
    </p>
  </div>
</template>

<script lang="ts"
        setup>
import {computed, ref} from 'vue'

let props = withDefaults(defineProps<{
  count: number
  max?: number
  min?: number
}>(), {
  min: 1,
  max: Number.MAX_VALUE
})

let emits = defineEmits<{
  (e: 'update:count', v: number): void
  (e: 'change', v: number): void
}>()

let eInput = ref<HTMLInputElement>()

let input = computed({
  get(): number {
    return props.count
  },
  set(val: number | string): void {
    if (typeof val === 'string') {
      val = val.replace(/\D+/, '')
      val = +val
    }
    if (val < props.min) val = props.min
    if (val > props.max) val = props.max
    // 此处刷新input输入框的值
    if (eInput.value)
      eInput.value.value = val + ''
    emits('update:count', val)
    emits('change', val)
  }
})

let handleFocusout = (e: FocusEvent) => {
  if (e?.target?.value === '' && eInput.value)
    eInput.value.value = props.min + ''
}
</script>

<style lang="less"
       scoped>
.count {
  width: 120px;
  height: 30px;
  border: 1px solid #e4e4e4;
  display: flex;

  p {
    width: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #f8f8f8;
    font-size: 18px;
    color: #666666;
    cursor: pointer;

    &.disable {
      cursor: not-allowed;
      color: #999999;
      background-color: #efefef;
    }

    &.decrement {
      border-right: 1px solid #e4e4e4;
    }

    &.increment {
      border-left: 1px solid #e4e4e4;
    }
  }

  div {
    flex: 1;

    input {
      text-align: center;
      width: 100%;
      height: 100%;
    }
  }
}
</style>